{% extends "base.html" %}

{% block title %}模型推理 - {{ project.name }} - AI模型训练平台{% endblock %}

{% block content %}
<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        <li class="breadcrumb-item"><a href="{{ url_for('main.index') }}">项目列表</a></li>
        <li class="breadcrumb-item"><a href="{{ url_for('main.project_detail', project_id=project.id) }}">{{ project.name }}</a></li>
        <li class="breadcrumb-item active" aria-current="page">模型推理</li>
    </ol>
</nav>

<div class="d-flex justify-content-between align-items-center mb-4">
    <h1>AI模型训练平台 - 模型推理</h1>
</div>

<ul class="nav nav-tabs mb-4">
    <li class="nav-item">
        <a class="nav-link" href="{{ url_for('main.project_detail', project_id=project.id) }}">
            <i class="fas fa-tachometer-alt"></i> 项目概览
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="{{ url_for('main.project_images', project_id=project.id) }}">
            <i class="fas fa-images"></i> 图片管理
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="{{ url_for('main.annotate', project_id=project.id) }}">
            <i class="fas fa-object-group"></i> 图片标注
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="{{ url_for('main.project_dataset', project_id=project.id) }}">
            <i class="fas fa-database"></i> 数据集划分
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="{{ url_for('main.project_train', project_id=project.id) }}">
            <i class="fas fa-brain"></i> 模型训练
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="{{ url_for('main.project_export', project_id=project.id) }}">
            <i class="fas fa-file-export"></i> 模型导出
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link active" href="{{ url_for('main.model_inference', project_id=project.id) }}">
            <i class="fas fa-magic"></i> 模型推理
        </a>
    </li>
</ul>

<div class="row">
    <div class="col-md-4">
        <div class="card mb-4">
            <div class="card-header">
                <i class="fas fa-cog me-1"></i>模型选择
            </div>
            <div class="card-body">
                <form id="modelSelectionForm">
                    <div class="mb-3">
                        <label class="form-label">选择模型</label>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="modelType" id="systemModel" value="system" checked>
                            <label class="form-check-label" for="systemModel">
                                使用系统训练模型
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="modelType" id="uploadModel" value="upload">
                            <label class="form-check-label" for="uploadModel">
                                上传模型文件
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="modelType" id="uploadedModel" value="uploaded">
                            <label class="form-check-label" for="uploadedModel">
                                已上传模型
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="modelType" id="existingModel" value="existing">
                            <label class="form-check-label" for="existingModel">
                                已存在模型
                            </label>
                        </div>
                    </div>

                    <div id="systemModelOptions">
                        <div class="mb-3">
                            <label for="systemModelSelect" class="form-label">系统模型</label>
                            <select class="form-select" id="systemModelSelect">
                                <option value="">选择系统训练的模型</option>
                                {% if best_model_exists %}
                                <option value="best.pt">best.pt (项目训练的最佳模型)</option>
                                {% endif %}
                                {% if last_model_exists %}
                                <option value="last.pt">last.pt (项目最后训练的模型)</option>
                                {% endif %}
                            </select>
                        </div>
                    </div>

                    <div id="uploadModelOptions" style="display: none;">
                        <div class="mb-3">
                            <label for="modelFile" class="form-label">上传模型文件</label>
                            <input class="form-control" type="file" id="modelFile" accept=".pt">
                            <div class="form-text">支持YOLOv8格式的.pt模型文件</div>
                        </div>
                    </div>

                    <div id="uploadedModelOptions" style="display: none;">
                        <div class="mb-3">
                            <label for="uploadedModelSelect" class="form-label">已上传模型</label>
                            <select class="form-select" id="uploadedModelSelect">
                                <option value="">选择已上传的模型文件</option>
                                {% for model in uploaded_models %}
                                <option value="{{ model }}">{{ model }}</option>
                                {% endfor %}
                            </select>
                            <div class="form-text">从已上传模型目录中选择模型文件</div>
                        </div>
                    </div>

                    <div id="existingModelOptions" style="display: none;">
                        <div class="mb-3">
                            <label for="existingModelSelect" class="form-label">已存在模型</label>
                            <select class="form-select" id="existingModelSelect">
                                <option value="">选择已存在的模型文件</option>
                                {% for model in existing_models %}
                                <option value="{{ model }}">{{ model }}</option>
                                {% endfor %}
                            </select>
                            <div class="form-text">从项目模型目录中选择已存在的模型文件</div>
                        </div>
                    </div>
                </form>
            </div>
        </div>

        <div class="card">
            <div class="card-header">
                <i class="fas fa-play-circle me-1"></i>推理选项
            </div>
            <div class="card-body">
                <form id="inferenceForm">
                    <div class="mb-3">
                        <label class="form-label">推理类型</label>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="inferenceType" id="imageInference" value="image" checked>
                            <label class="form-check-label" for="imageInference">
                                图片推理
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="inferenceType" id="videoInference" value="video">
                            <label class="form-check-label" for="videoInference">
                                视频推理
                            </label>
                        </div>
                        <div class="form-check">
                        <input class="form-check-input" type="radio" name="inferenceType" id="rtspInference" value="rtsp">
                        <label class="form-check-label" for="rtspInference">
                            RTSP推理 (保存视频)
                        </label>
                    </div>
                    <div class="form-check">
                        <input class="form-check-input" type="radio" name="inferenceType" id="rtspStream" value="rtsp_stream">
                        <label class="form-check-label" for="rtspStream">
                            RTSP实时流推理
                        </label>
                    </div>
                    </div>

                    <div id="imageInput" class="mb-3">
                        <label for="imageFile" class="form-label">选择图片</label>
                        <input class="form-control" type="file" id="imageFile" accept="image/*">
                    </div>

                    <div id="videoInput" class="mb-3" style="display: none;">
                        <label for="videoFile" class="form-label">选择视频</label>
                        <input class="form-control" type="file" id="videoFile" accept="video/*">
                    </div>

                    <div id="rtspInput" class="mb-3" style="display: none;">
                        <label for="rtspUrl" class="form-label">RTSP流地址</label>
                        <input class="form-control" type="text" id="rtspUrl" placeholder="rtsp://username:password@ip:port/path">
                    </div>


                    <button type="button" class="btn btn-primary" id="runInference">
                        <i class="fas fa-play me-1"></i>开始推理
                    </button>
                </form>
            </div>
        </div>
    </div>

    <div class="col-md-8">
        <div class="card">
            <div class="card-header">
                <i class="fas fa-eye me-1"></i>推理结果
            </div>
            <div class="card-body">
                <div id="inferenceResult" class="text-center">
                    <div class="py-5">
                        <i class="fas fa-cloud-upload-alt fa-3x text-muted mb-3"></i>
                        <h4 class="text-muted">等待推理结果</h4>
                        <p class="text-muted">选择模型和推理选项，然后点击开始推理</p>
                    </div>
                </div>
                <div id="inferenceLoading" class="text-center" style="display: none;">
                    <div class="spinner-border" role="status">
                        <span class="visually-hidden">推理中...</span>
                    </div>
                    <p class="mt-2">推理中，请稍候...</p>
                </div>
            </div>
        </div>
    </div>
</div>

<style>
.result-image-container {
    position: relative;
    display: inline-block;
    max-width: 100%;
}

.result-image {
    max-width: 100%;
    height: auto;
}

.detection-box {
    position: absolute;
    border: 2px solid #ff0000;
}

.detection-label {
    position: absolute;
    background-color: #ff0000;
    color: white;
    font-size: 12px;
    padding: 2px 4px;
    white-space: nowrap;
}
</style>
{% endblock %}

{% block extra_js %}
<script>
// 确保jQuery已加载
function initializeInferencePage() {
    // 模型类型切换
    const modelTypeRadios = document.querySelectorAll('input[name="modelType"]');
    modelTypeRadios.forEach(radio => {
        radio.addEventListener('change', function() {
            document.getElementById('systemModelOptions').style.display = 'none';
            document.getElementById('uploadModelOptions').style.display = 'none';
            document.getElementById('uploadedModelOptions').style.display = 'none';
            document.getElementById('existingModelOptions').style.display = 'none';
            
            if (this.value === 'system') {
                document.getElementById('systemModelOptions').style.display = 'block';
            } else if (this.value === 'upload') {
                document.getElementById('uploadModelOptions').style.display = 'block';
            } else if (this.value === 'uploaded') {
                document.getElementById('uploadedModelOptions').style.display = 'block';
            } else if (this.value === 'existing') {
                document.getElementById('existingModelOptions').style.display = 'block';
            }
        });
    });
    
    // 初始化时根据选中的模型类型显示相应选项
    const checkedModelType = document.querySelector('input[name="modelType"]:checked');
    if (checkedModelType) {
        document.getElementById('systemModelOptions').style.display = 'none';
        document.getElementById('uploadModelOptions').style.display = 'none';
        document.getElementById('uploadedModelOptions').style.display = 'none';
        document.getElementById('existingModelOptions').style.display = 'none';
        
        if (checkedModelType.value === 'system') {
            document.getElementById('systemModelOptions').style.display = 'block';
        } else if (checkedModelType.value === 'upload') {
            document.getElementById('uploadModelOptions').style.display = 'block';
        } else if (checkedModelType.value === 'uploaded') {
            document.getElementById('uploadedModelOptions').style.display = 'block';
        } else if (checkedModelType.value === 'existing') {
            document.getElementById('existingModelOptions').style.display = 'block';
        }
    }

    // 推理类型切换
    const inferenceTypeRadios = document.querySelectorAll('input[name="inferenceType"]');
    inferenceTypeRadios.forEach(radio => {
        radio.addEventListener('change', function() {
            document.getElementById('imageInput').style.display = 'none';
            document.getElementById('videoInput').style.display = 'none';
            document.getElementById('rtspInput').style.display = 'none';

            if (this.value === 'image') {
                document.getElementById('imageInput').style.display = 'block';
            } else if (this.value === 'video') {
                document.getElementById('videoInput').style.display = 'block';
            } else if (this.value === 'rtsp' || this.value === 'rtsp_stream') {
                document.getElementById('rtspInput').style.display = 'block';
            }
        });
    });
    
    // 初始化时根据选中的推理类型显示相应选项
    const checkedInferenceType = document.querySelector('input[name="inferenceType"]:checked');
    if (checkedInferenceType) {
        document.getElementById('imageInput').style.display = 'none';
        document.getElementById('videoInput').style.display = 'none';
        document.getElementById('rtspInput').style.display = 'none';
        
        if (checkedInferenceType.value === 'image') {
            document.getElementById('imageInput').style.display = 'block';
        } else if (checkedInferenceType.value === 'video') {
            document.getElementById('videoInput').style.display = 'block';
        } else if (checkedInferenceType.value === 'rtsp' || checkedInferenceType.value === 'rtsp_stream') {
            document.getElementById('rtspInput').style.display = 'block';
        }
    } else {
        // 默认显示图片输入
        document.getElementById('imageInput').style.display = 'block';
        document.getElementById('videoInput').style.display = 'none';
        document.getElementById('rtspInput').style.display = 'none';
    }

    // 开始推理
    document.getElementById('runInference').addEventListener('click', function() {
        const modelType = document.querySelector('input[name="modelType"]:checked').value;
        const inferenceType = document.querySelector('input[name="inferenceType"]:checked').value;
        const systemModelSelect = document.getElementById('systemModelSelect');
        const modelFileInput = document.getElementById('modelFile');
        const uploadedModelSelect = document.getElementById('uploadedModelSelect');
        const existingModelSelect = document.getElementById('existingModelSelect');
        const imageFileInput = document.getElementById('imageFile');
        const videoFileInput = document.getElementById('videoFile');
        const rtspUrlInput = document.getElementById('rtspUrl');

        // 验证输入
        if (modelType === 'system' && !systemModelSelect.value) {
            alert('请选择系统模型');
            return;
        }

        if (modelType === 'upload' && !modelFileInput.files.length) {
            alert('请上传模型文件');
            return;
        }

        if (modelType === 'uploaded' && !uploadedModelSelect.value) {
            alert('请选择已上传模型');
            return;
        }

        if (modelType === 'existing' && !existingModelSelect.value) {
            alert('请选择已存在模型');
            return;
        }

        if (inferenceType === 'image' && !imageFileInput.files.length) {
            alert('请选择图片文件');
            return;
        }

        if (inferenceType === 'video' && !videoFileInput.files.length) {
            alert('请选择视频文件');
            return;
        }

        if ((inferenceType === 'rtsp' || inferenceType === 'rtsp_stream') && !rtspUrlInput.value.trim()) {
            alert('请输入RTSP流地址');
            return;
        }

        // 如果是RTSP实时流，跳转到专门的实时流页面
        if (inferenceType === 'rtsp_stream') {
            const rtspUrl = encodeURIComponent(rtspUrlInput.value.trim());
            let modelParam = '';
            
            if (modelType === 'system') {
                let systemModelValue = systemModelSelect.value;
                // 转换模型名称格式以匹配rtsp_stream页面
                if (systemModelValue === 'best.pt') {
                    systemModelValue = 'best';
                } else if (systemModelValue === 'last.pt') {
                    systemModelValue = 'last';
                }
                modelParam = `&system_model=${encodeURIComponent(systemModelValue)}`;
            } else if (modelType === 'uploaded') {
                modelParam = `&uploaded_model=${encodeURIComponent(uploadedModelSelect.value)}`;
            } else if (modelType === 'existing') {
                modelParam = `&existing_model=${encodeURIComponent(existingModelSelect.value)}`;
            }
            
            const streamUrl = `{{ url_for('main.rtsp_stream_page', project_id=project.id) }}?rtsp_url=${rtspUrl}&model_type=${modelType}${modelParam}`;
            window.open(streamUrl, '_blank');
            return;
        }

        // 显示加载状态
        document.getElementById('inferenceResult').style.display = 'none';
        document.getElementById('inferenceLoading').style.display = 'block';

        // 构建表单数据
        const formData = new FormData();
        formData.append('model_type', modelType);
        formData.append('inference_type', inferenceType);

        if (modelType === 'system') {
            formData.append('system_model', systemModelSelect.value);
        } else if (modelType === 'upload') {
            formData.append('model_file', modelFileInput.files[0]);
        } else if (modelType === 'uploaded') {
            formData.append('uploaded_model', uploadedModelSelect.value);
        } else if (modelType === 'existing') {
            formData.append('existing_model', existingModelSelect.value);
        }

        if (inferenceType === 'image') {
            formData.append('image_file', imageFileInput.files[0]);
        } else if (inferenceType === 'video') {
            formData.append('video_file', videoFileInput.files[0]);
        } else if (inferenceType === 'rtsp') {
            formData.append('rtsp_url', rtspUrlInput.value.trim());
        }

        // 发送请求
        fetch('{{ url_for("main.run_inference", project_id=project.id) }}', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(response => {
            document.getElementById('inferenceLoading').style.display = 'none';
            if (response.success) {
                displayInferenceResult(response.result);
            } else {
                document.getElementById('inferenceResult').innerHTML = `
                    <div class="alert alert-danger">
                        <h5><i class="fas fa-exclamation-triangle"></i> 推理失败</h5>
                        <p>${response.error}</p>
                    </div>
                `;
                document.getElementById('inferenceResult').style.display = 'block';
            }
        })
        .catch(error => {
            document.getElementById('inferenceLoading').style.display = 'none';
            document.getElementById('inferenceResult').innerHTML = `
                <div class="alert alert-danger">
                    <h5><i class="fas fa-exclamation-triangle"></i> 请求失败</h5>
                    <p>${error}</p>
                </div>
            `;
            document.getElementById('inferenceResult').style.display = 'block';
        });
    });

    // 显示推理结果
    function displayInferenceResult(result) {
        let resultHtml = '';
        if (result.type === 'image') {
            resultHtml = `
                <div class="result-image-container">
                    <img src="${result.image_url}" class="result-image" alt="推理结果">
            `;

            // 不再绘制检测框，因为图片上已经标注了
            // 只显示检测到的对象总数
            resultHtml += `</div>`;
            resultHtml += `<p class="mt-3">检测到 ${result.detections.length} 个对象</p>`;
        } else if (result.type === 'video' || result.type === 'rtsp') {
            let videoHtml = '';
            if (result.video_url) {
                videoHtml = `
                    <div class="mb-3">
                        <video controls class="img-fluid" preload="metadata">
                            <source src="${result.video_url}" type="video/mp4">
                            您的浏览器不支持视频播放。
                        </video>
                    </div>
                `;
            } else {
                videoHtml = `
                    <div class="alert alert-warning" role="alert">
                        <i class="fas fa-exclamation-triangle"></i>
                        视频文件生成失败，请检查RTSP流地址是否正确。
                    </div>
                `;
            }
            
            resultHtml = videoHtml + `
                <div>
                    <h5>推理统计信息</h5>
                    <ul class="list-unstyled">
                        <li>处理帧数: ${result.processed_frames}</li>
                        <li>视频帧率: ${result.fps}</li>
            `;
            
            if (result.type === 'video') {
                resultHtml += `<li>总帧数: ${result.total_frames}</li>`;
            }
            
            if (result.error_message) {
                resultHtml += `<li class="text-danger">错误信息: ${result.error_message}</li>`;
            }
            
            resultHtml += `
                    </ul>
                </div>
            `;
        } else {
            resultHtml = `
                <div class="alert alert-info">
                    <h5><i class="fas fa-info-circle"></i> 推理完成</h5>
                    <p>推理已完成，类型: ${result.type}</p>
                </div>
            `;
        }
        
        document.getElementById('inferenceResult').innerHTML = resultHtml;
        document.getElementById('inferenceResult').style.display = 'block';
    }
}

// 页面加载完成后初始化
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initializeInferencePage);
} else {
    initializeInferencePage();
}
</script>
{% endblock %}